import type { ViewCalendarScope } from '../type'
import constVal from './const'
import DateClass from './DateClass'
import { clockFactory } from './func'

/**
 * 获得节气
 * @param y 农历年度
 * @param m 公立月份
 * @param d 公立日期
 * @returns
 */
export function getTerm(y: number, m: number, d: number) {
  const firstNode = DateClass.getTerm(y, m * 2 - 1)
  const secondNode = DateClass.getTerm(y, m * 2)
  let term: false | string = false

  if (Number(firstNode) === d)
    term = constVal.solarTerm[m * 2 - 2]!
  if (Number(secondNode) === d)
    term = constVal.solarTerm[m * 2 - 1]!

  return term
}

class Calendar {
  worksTime: string[] = []
  holidaysTime: string[] = []

  title() {
    const title: string[] = []
    for (let i = 0; i <= 6; i++) {
      title.push(constVal.nStr1[i % 7]!)
    }
    return title
  }

  validateDate(date: number[]) {
    if (date.length === 3 && String(date[0]).length === 4) {
      return date
    }
    else {
      return DateClass.getCurrent()
    }
  }

  getDateParams(day: ViewCalendarScope[]) {
    return day.map((el) => {
      return {
        title: el.title,
        isCurrent: el.isCurrent,
        value: `tCalendar${new Date().getTime()}`,
        isWeek:
          new Date(el.date).getDay() === 6 || new Date(el.date).getDay() === 0,
        isHolidays: el.isHolidays,
        isWorks: el.isWorks,
        date: el.date,
        lunars: el.lunars,
        lunarsChinese: el.lunarsChinese,
        lunarsChina: el.lunarDay || el.solarDay || el.term || el.lunarsChina,
        isNow: el.isNow,
        animal: el.animal,
        astro: el.astro,
        term: el.term,
        solarDay: el.solarDay,
        lunarDay: el.lunarDay,
      }
    })
  }

  /**
   * 获取当月前面需补齐的数组
   */
  beforDays(date: number[], last: number) {
    const y = date[1] === 1 ? date[0]! - 1 : date[0]!
    const m = date[1] === 1 ? 12 : date[1]! - 1
    const w = DateClass.solarMonth(y!, m)!

    const arr: ViewCalendarScope[] = []
    for (let i = 0; i < last; i++) {
      const lun = DateClass.getLunars(y!, m, w! - i)
      const l = lun.split('-')
      arr.push({
        title: w! - i,
        isCurrent: false,
        isWorks: DateClass.getWorks([y!, m, w! - i], this.worksTime),
        isHolidays: DateClass.getHolidays([y!, m, w! - i], this.holidaysTime),
        date: `${y}-${clockFactory(m)}-${clockFactory(w! - i)}`,
        lunars: lun,
        lunarsChinese:
          DateClass.toChinaMonth(Number(l[1]))
          + DateClass.toChinaDay(Number(l[2])),
        lunarsChina: DateClass.toChinaDay(Number(l[2])),
        isNow: false,
        solarDay: DateClass.getSolarDay(m, w! - i),
        lunarDay: DateClass.getlunarDay(
          Number(l[0]),
          Number(l[1]),
          Number(l[2]),
        ),
        animal: DateClass.getAnimal(Number(l[0])),
        astro: DateClass.toAstro(y, m),
        term: getTerm(Number(l[0]), m, w - i),
      })
    }
    return arr
  }

  /**
   * 获取当月后面需补齐的数组
   */
  afterDays(day: ViewCalendarScope[], date: number[]) {
    const arr: ViewCalendarScope[] = []
    const y = date[1] === 12 ? date[0]! + 1 : date[0]!
    const m = date[1] === 12 ? 1 : date[1]! + 1

    for (let i = 1; i < 42 - day.length + 1; i++) {
      const lun = DateClass.getLunars(y, m, i)
      const l = lun.split('-')
      arr.push({
        title: i,
        isCurrent: false,
        isHolidays: DateClass.getHolidays([y, m, i], this.holidaysTime),
        isWorks: DateClass.getWorks([y, m, i], this.worksTime),
        date: `${y}-${clockFactory(m)}-${clockFactory(i)}`,
        lunars: lun,
        lunarsChinese:
          DateClass.toChinaMonth(Number(l[1]))
          + DateClass.toChinaDay(Number(l[2])),
        lunarsChina: DateClass.toChinaDay(Number(l[2])),
        isNow: false,
        solarDay: DateClass.getSolarDay(m, i),
        lunarDay: DateClass.getlunarDay(
          Number(l[0]),
          Number(l[1]),
          Number(l[2]),
        ),
        animal: DateClass.getAnimal(Number(l[0])),
        astro: DateClass.toAstro(y, m),
        term: getTerm(Number(l[0]), m, i),
      })
    }
    return [...day, ...arr]
  }

  getDay(date: number[], beforDays: ViewCalendarScope[]) {
    const dateArray: ViewCalendarScope[] = []
    const currentDayNumber = DateClass.solarMonth(date[0]!, date[1]!)
    for (let i = 1; i <= currentDayNumber; i++) {
      const lun = DateClass.getLunars(date[0]!, date[1]!, i)
      const l = lun.split('-')
      dateArray.push({
        title: i,
        isCurrent: true,
        isHolidays: DateClass.getHolidays(
          [date[0]!, date[1]!, i],
          this.holidaysTime,
        ),
        isWorks: DateClass.getWorks([date[0]!, date[1]!, i], this.worksTime),
        date: `${date[0]}-${clockFactory(date[1]!)}-${clockFactory(i)}`,
        lunars: lun,
        lunarsChinese:
          DateClass.toChinaMonth(Number(l[1]))
          + DateClass.toChinaDay(Number(l[2])),
        lunarsChina: DateClass.toChinaDay(Number(l[2])),
        isNow: i === date[2],
        solarDay: DateClass.getSolarDay(date[1]!, i),
        lunarDay: DateClass.getlunarDay(
          Number(l[0]),
          Number(l[1]),
          Number(l[2]),
        ),
        animal: DateClass.getAnimal(Number(l[0])),
        astro: DateClass.toAstro(date[0]!, date[1]!),
        term: getTerm(Number(l[0]), date[1]!, i),
      })
    }
    return [...beforDays, ...dateArray]
  }

  table(date: number[], worksTime: string[], holidaysTime: string[]) {
    this.worksTime = worksTime
    this.holidaysTime = holidaysTime
    const dateArray = []

    const result = this.validateDate(date)

    const currentDay = DateClass.solarWeeks(result[0]!, result[1]!)

    // 获取当月的完整数据
    const beforDays = this.beforDays(date, currentDay).reverse()

    const m = this.getDay(date, beforDays)
    const afterDays = this.afterDays(m, date)

    // 转化成参数
    const params = this.getDateParams(afterDays)

    // return [];
    if (params.length !== 42)
      return []

    for (let row = 0; row < 6; row++) {
      dateArray.push(params.splice(0, 7))
    }
    return dateArray
  }
}

export default new Calendar()
